using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LevelData;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Media;
using GGJ11.Resources;

namespace GGJ11
{
    class RenderingState: RenderingBlocks
    {
        Level level;
        private float cameraPositionX;
        private float cameraPositionY;

        Texture2D background;
        Texture2D infoDie;
        Texture2D infoStory;
        Texture2D imageStory;
        Texture2D life;
        SpriteFont font;
        SpriteFont fontStory;

        Vector2 position = Vector2.Zero;


        public RenderingState() { }
        public RenderingState(ContentManager Content)
            : base(Content)
        {
            level = Content.ServiceProvider.GetService(typeof(Level)) as Level;
            background = Content.Load<Texture2D>("Backgrounds/Layer" + level.numLevel.ToString());
            font = Content.Load<SpriteFont>("Fonts/Hud");
            fontStory = Content.Load<SpriteFont>("Fonts/storyFont");
            infoDie = Content.Load<Texture2D>("Textures/you_died");
            infoStory = Content.Load<Texture2D>("Textures/infoStory");
            imageStory = Content.Load<Texture2D>("Textures/storyImage0");//+ level.numLevel.ToString());
            life = Content.Load<Texture2D>("Sprites/MonsterA/life");
        }

        public void Draw(GameTime gameTime, SpriteBatch sp)
        {
            if (level.storyMode)
            {
                String levelString = GetLevel(level.numLevel);
                if (position == Vector2.Zero)
                     position = new Vector2(sp.GraphicsDevice.Viewport.Width / 2 - 160, (int)(sp.GraphicsDevice.Viewport.Height / 3));

                sp.Begin();

                sp.Draw(imageStory, new Rectangle(0, 0, sp.GraphicsDevice.Viewport.Width, sp.GraphicsDevice.Viewport.Height), Color.White);
                position.Y -= (float)(gameTime.ElapsedGameTime.TotalMilliseconds / 50);
                sp.DrawString(fontStory, levelString, new Vector2(position.X, position.Y), Color.WhiteSmoke);

                sp.End();
            }
            else
            {
                position = Vector2.Zero;
                //draw background
                sp.Begin();
                sp.Draw(background, new Rectangle(0, 0, sp.GraphicsDevice.Viewport.Width, sp.GraphicsDevice.Viewport.Height), Color.White);
                sp.End();

                //manage the camera for follow the player
                ScrollCamera(sp.GraphicsDevice.Viewport);

                Matrix cameraTransform = Matrix.CreateTranslation(-cameraPositionX, -cameraPositionY, 0.0f);

                //draw the scene
                sp.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone, null, cameraTransform);
                Vector2 visibleHArea = level.checkVisibleHArea(cameraPositionX);
                Vector2 visibleVArea = level.checkVisibleVArea(cameraPositionY);
                base.Draw(gameTime, sp, visibleHArea, visibleVArea);
                sp.End();

                DrawHud(sp);

                if (level.playerLevel.isAlive == false && level.menuDieTime <= 0.0f)
                {
                    sp.Begin();
                    sp.Draw(infoDie, new Rectangle(sp.GraphicsDevice.Viewport.Width / 2 - infoDie.Width / 2,
                                                   sp.GraphicsDevice.Viewport.Height / 2 - infoDie.Height / 2,
                                                   infoDie.Width, infoDie.Height), Color.White);
                    sp.End();
                    level.menuDieTime = 0.0f;
                }

                //if (level.playerLevel.onExit == true)
                //{
                //    sp.Begin();
                //    sp.Draw(infoWin, new Rectangle(sp.GraphicsDevice.Viewport.Width / 2 - infoWin.Width / 2,
                //                                   sp.GraphicsDevice.Viewport.Height / 2 - infoWin.Height / 2,
                //                                   infoWin.Width, infoWin.Height), Color.White);
                //    sp.End();
                //}
            }
        }

        private void DrawHud(SpriteBatch sp)
        {

            //draw the statistic
            Rectangle titleSafeArea = sp.GraphicsDevice.Viewport.TitleSafeArea;
            Vector2 hudLocation = new Vector2(titleSafeArea.X, titleSafeArea.Y);
            sp.Begin();
            sp.DrawString(font, "POINTS: " + level.playerLevel.points.ToString(), hudLocation + new Vector2(0, 40), Color.White);
            sp.DrawString(font, "LIFE: " + level.playerLevel.life.ToString(), hudLocation + new Vector2(0, 20), Color.White);
            sp.DrawString(font, "HEALTH: ", hudLocation, Color.White);
            for (int i = 0; i < level.playerLevel.health; i++)
            {
                sp.Draw(life, new Rectangle((int)hudLocation.X + 90 + i * 15, (int)hudLocation.Y + 5, 15, 15), Color.White);
            }
            sp.DrawString(font, "TIME: " + ((int)(level.totalGameTime)).ToString() + "s", hudLocation + new Vector2(0, 60), Color.White);
            sp.DrawString(font, "LEVEL: " + ((int)(level.numLevel + 1)).ToString(), new Vector2(sp.GraphicsDevice.Viewport.Width / 2 - 50, sp.GraphicsDevice.Viewport.Height - 20), Color.White);
            sp.End();

         
        }

        //manage the camera
        private void ScrollCamera(Viewport viewport)
        {
            const float ViewMargin = 0.5f;

            // Calculate the edges of the screen.
            float marginWidth = viewport.Width * ViewMargin;
            float marginLeft = cameraPositionX + marginWidth;
            float marginRight = cameraPositionX + viewport.Width - marginWidth;

            float marginHeight = viewport.Height * ViewMargin;
            float marginTop = cameraPositionY + marginHeight;
            float marginBottom = cameraPositionY + viewport.Height - marginHeight;

            // Calculate how far to scroll when the player is near the edges of the screen.
            float cameraMovementX = 0.0f;
            float cameraMovementY = 0.0f;

            if (level.playerLevel.position.X < marginLeft)
                cameraMovementX = level.playerLevel.position.X - marginLeft;
            else if (level.playerLevel.position.X > marginRight)
                cameraMovementX = level.playerLevel.position.X - marginRight;

            if (level.playerLevel.position.Y < marginTop)
                cameraMovementY = level.playerLevel.position.Y - marginTop;
            else if (level.playerLevel.position.Y > marginBottom)
                cameraMovementY = level.playerLevel.position.Y - marginBottom;

            // Update the camera position, but prevent scrolling off the ends of the level.
            float maxCameraPositionX = Tile.Width * level.lenghtX - viewport.Width;

            cameraPositionX = MathHelper.Clamp(cameraPositionX + cameraMovementX, 0.0f, maxCameraPositionX);

            if (cameraPositionY + cameraMovementY <= level.lenghtY * Tile.Height - viewport.Height)
                cameraPositionY = cameraPositionY + cameraMovementY;
            else
                cameraPositionY = level.lenghtY * Tile.Height - viewport.Height;
        }

        //update the service when load a next level
        public void UpdateLevelService(ContentManager content)
        {
            level = content.ServiceProvider.GetService(typeof(Level)) as Level;
            background = content.Load<Texture2D>("Backgrounds/Layer" + level.numLevel.ToString());
            //imageStory = content.Load<Texture2D>("Textures/storyImage"+ level.numLevel.ToString());
            base.UpdateLevelService(content);

        }

        private string GetLevel(int i)
        {
            switch (i)
            { 
                case 0:
                    return Strings.level0;
                case 1:
                    return Strings.level1;
                case 2:
                    return Strings.level2;
                case 3:
                    return Strings.level3;
                case 4:
                    return Strings.level4;
                case 5:
                    return Strings.level5;
                case 6:
                    return Strings.level6;
                case 7:
                    return Strings.level7;
                case 8:
                    return Strings.level8;
                case 9:
                    return Strings.level9;
                case 10:
                    return Strings.level10;
                case 11:
                    return Strings.level11;
                case 12:
                    return Strings.level12;
                case 13:
                    return Strings.level13;
                case 14:
                    return Strings.level14;
                case 15:
                    return Strings.level15;
                case 16:
                    return Strings.level16;
                case 17:
                    return Strings.level17;
                case 18:
                    return Strings.level18;
                case 19:
                    return Strings.level19;
                case 20:
                    return Strings.level20;
                case 21:
                    return Strings.level21;
                case 22:
                    return Strings.level22;
                case 23:
                    return Strings.level23;
                case 24:
                    return Strings.level24;
                case 25:
                    return Strings.level25;
                case 26:
                    return Strings.level26;
                case 27:
                    return Strings.level27;
                case 28:
                    return Strings.level28;
                case 29:
                    return Strings.level29;
                default:
                    return "";
            }
        }
    }
}

